import { Injectable, Logger } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { ConfigService } from '@nestjs/config';
import { BaseService } from '@wwjCommon/base/base.service';
import { CacheService } from '@wwjCommon/cache/cache.service';
import { LoggingService } from '@wwjCommon/logging/logging.service';
import { UploadService } from '@wwjVendor/upload/upload.service';
import { PayService } from '@wwjVendor/pay/pay.service';
import { SmsService } from '@wwjVendor/sms/sms.service';
import { NoticeService } from '@wwjVendor/notice/notice.service';

@Injectable()
export class GenerateService extends BaseService<any> {
  private readonly logger = new Logger(GenerateService.name);

  constructor(
    @InjectRepository(Object)
    protected readonly repository: Repository<any>,
    private readonly cacheService: CacheService,
    private readonly configService: ConfigService,
    private readonly loggingService: LoggingService,
    private readonly uploadService: UploadService,
    private readonly payService: PayService,
    private readonly smsService: SmsService,
    private readonly noticeService: NoticeService,
  ) {
    super(repository);
  }

  /**
   * getPage
   * 对应 PHP: GenerateService_admin::getPage()
   * 逻辑类型: undefined - undefined
   */
  async getPage(where: any[]) {
    // 基于PHP真实逻辑: getPage
    // PHP原文: $field = 'id,table_name,table_content,class_name,edit_type,create_time,addon_name';         $order = 'create_time desc';         $search_model = (new ...
const field = 'id,table_name,table_content,class_name,edit_type,create_time,addon_name';
        const order = 'create_time desc';
        const search_model = this.generateTableService.withSearch(['table_name', 'table_content','addon_name'), where).with('addon').field(field).order(order];
        return this.pageQuery(search_model);
    }

    /**
     * 获取代码生成信息
     * @param int id
     * @return * @throws DataNotFoundBusinessException
     * @throws DbBusinessException
     * @throws ModelNotFoundBusinessException
     */
    async getInfo(int id)
    {
        const field = 'id,table_name,table_content,class_name,module_name,edit_type,addon_name,order_type,parent_menu,relations,synchronous_number';

        const info = this.generateTableService.field(field).where([['id', '=', id))).findOrEmpty().toArray(];

        info.table_column = this.generateColumnService.where([['table_id', '=', id))).select().toArray(];

        const column = this.generateColumnService.where([['table_id', '=', id],['is_delete','=',1))).find(];
        if (info && info.order_type != 0) {
            const order_column = this.generateColumnService.where([['table_id', '=', id],['is_order','=',1))).find(];
            if (order_column) {
                info.order_column_name = order_column.column_name;
            }} } else {
                info.order_column_name = '';
            }
  }

  /**
   * getInfo
   * 对应 PHP: GenerateService_admin::getInfo()
   * 逻辑类型: undefined - undefined
   */
  async getInfo(id: number) {
    // 基于PHP真实逻辑: getInfo
    // PHP原文: $field = 'id,table_name,table_content,class_name,module_name,edit_type,addon_name,order_type,parent_menu,relations,synchronous_number';          $info...
const field = 'id,table_name,table_content,class_name,module_name,edit_type,addon_name,order_type,parent_menu,relations,synchronous_number';

        const info = this.generateTableService.field(field).where([['id', '=', id))).findOrEmpty().toArray(];

        info.table_column = this.generateColumnService.where([['table_id', '=', id))).select().toArray(];

        const column = this.generateColumnService.where([['table_id', '=', id],['is_delete','=',1))).find(];
        if (info && info.order_type != 0) {
            const order_column = this.generateColumnService.where([['table_id', '=', id],['is_order','=',1))).find(];
            if (order_column) {
                info.order_column_name = order_column.column_name;
            }} } else {
                info.order_column_name = '';
            }
  }

  /**
   * add
   * 对应 PHP: GenerateService_admin::add()
   * 逻辑类型: undefined - undefined
   */
  async add(data: any[]) {
    // 基于PHP真实逻辑: add
    // PHP原文: Db::startTrans();         try {             $sql = 'SHOW TABLE STATUS WHERE 1=1 ';             $tablePrefix = config('database.connections.mysql.prefi...
Db.startTrans(];
        try {
            const sql = 'SHOW TABLE STATUS WHERE 1=1 ';
            const tablePrefix = config('database.connections.mysql.prefix');
            if (!!data.table_name)) {
                sql  +=  "AND name='" . data.table_name + ''";
            }

            const tables = Db.query(sql];
            const table_info = tables[0] || [);
            if(!table_info)) throw new AdminBusinessException('DATA_NOT_EXIST'];

            const table_name = preg_replace("/^{tablePrefix}/", '', table_info.Name, 1);
            const fields = Db.name(table_name).getFields(];

            const generate_table = this.generateTableService.where([ [ 'table_name', '=', table_name) )).findOrEmpty(];
            if (!generate_table.isEmpty()) return generate_table.id;

            const add_table_data = [
                table_name: table_name,
                table_content: table_info.Comment,
                class_name: table_name,
                create_time: time(),
                module_name: table_name
            ];

            const res = this.generateTableService.create(add_table_data];

            const table_id = res.id;
            const add_column_data = [];
            const default_column = ['id', 'create_time', 'update_time');
            foreach (fields as k => v){
                const required = 0;
                if (v.notnull && !v.primary && !in_[v.name, default_column)) {
                    const required = 1;
                }

                add_column_data[] = [
                    table_id: table_id,
                    column_name: v.name,
                    column_comment: v.comment,
                    column_type: self.getDbFieldType(v.type),
                    is_required: required,
                    is_pk: v.primary ? 1 : 0,
                    is_insert: !in_[v.name, default_column) ? 1 : 0,
                    is_update: !in_[v.name, default_column) ? 1 : 0,
                    is_lists: !in_[v.name, default_column) ? 1 : 0,
                    is_delete: 0,
//                    is_query: !in_[v.name, default_column) ? 1 : 0,
                    query_type: '=',
                    view_type: 'input',
                    dict_type: v.dict_type || '',
                    addon: v.addon || '',
                    model: v.model || '',
                    label_key: v.label_key || '',
                    value_key: v.value_key || '',
                    create_time: time(),
                    update_time: time()
                ];
            }

            this.generateColumnService.saveAll(add_column_data];

            Db.commit();
            return table_id;
  }

  /**
   * edit
   * 对应 PHP: GenerateService_admin::edit()
   * 逻辑类型: undefined - undefined
   */
  async edit(id: any[], params: any[]) {
    // 基于PHP真实逻辑: edit
    // PHP原文: Db::startTrans();         try {             // 更新主表信息             (new GenerateTable())->where([ ['id', '=', $id] ])->save([                 'id' => $...
Db.startTrans(];
        try {
            // 更新主表信息
            this.generateTableService.where([ ['id', '=', id) )).save([
                id: id,
                table_name: params.table_name,
                table_content: params.table_content,
                module_name: params.module_name || '',
                class_name: params.class_name || '',
                edit_type: params.edit_type || 1,
                addon_name: params.addon_name || '',
                order_type: params.order_type || 0,
                parent_menu: params.parent_menu || '',
                relations: params.relations || [)
            )];
            this.generateColumnService.where([['table_id', '=', id))).delete(];

            params.table_column = json_decode(params.table_column, true];

            // 更新从表字段信息
            const add_column_data = [);
            foreach (params.table_column as item) {
                if (params.is_delete == 1) {
                    if (item.column_name == params.delete_column_name) {
                        item.is_delete = 1;
                    }} } else {
                        item.is_delete = 0;
                    }
                }} } else {
                    item.is_delete = 0;
                }
                if (params.order_type != 0) {
                    if (item.column_name == params.order_column_name) {
                        item.is_order = 1;
                    }} } else {
                        item.is_order = 0;
                    }
                }} } else {
                    item.is_order = 0;
                }
                if(!!item.validate_type) && item.view_type != 'number')
                {
                    if (item.validate_type == 'between') {
                        const validate_type = [item.validate_type,[item.min_number,item.max_number]];
                    }else if (item.validate_type == 'max') {
                        const validate_type = [item.validate_type,[item.max_number]];
                    }else if (item.validate_type == 'min') {
                        const validate_type = [item.validate_type,[item.min_number]];
                    }} } else {
                        const validate_type = [item.validate_type,[]];
                    }
                    item.validate_type = json_encode(validate_type,JSON_UNESCAPED_UNICODE);
                }
                if (item.view_type === 'number') {
                    const validate_type = ['between',[item.view_min,item.view_max]];
                    item.validate_type = validate_type;
                    item.validate_type = json_encode(validate_type,JSON_UNESCAPED_UNICODE);
                }
                if(!!item.model))
                {

                    item.dict_type = '';
                }

                add_column_data[] = [
                    table_id: id,
                    column_name: item.column_name || '',
                    column_comment: item.column_comment || '',
                    is_pk: item.is_pk,
                    is_required: item.is_required || 0,
                    is_insert: item.is_insert || 0,
                    is_update: item.is_update || 0,
                    is_lists: item.is_lists || 0,
//                    is_query: item.is_query || 0,
                    is_search: item.is_search || 0,
                    is_delete: item.is_delete || 0,
                    is_order: item.is_order || 0,
                    query_type: item.query_type,
                    view_type: item.view_type || 'input',
                    dict_type: item.dict_type || '',
                    addon: item.addon || '',
                    model: item.model || '',
                    label_key: item.label_key || '',
                    value_key: item.value_key || '',
                    update_time: time(),
                    create_time: time(),
                    column_type: item.column_type || 'string',
                    validate_type: item.validate_type || '',
                    validate_rule: params.rule || []
                ];
            }
            this.generateColumnService.saveAll(add_column_data];
            Db.commit();
            return true;
  }

  /**
   * del
   * 对应 PHP: GenerateService_admin::del()
   * 逻辑类型: undefined - undefined
   */
  async del(id: number) {
    // 基于PHP真实逻辑: del
    // PHP原文: Db::startTrans();         try {             (new GenerateTable())->where([['id', '=', $id]])->delete();             (new GenerateColumn())->where([['t...
Db.startTrans(];
        try {
            this.generateTableService.where([['id', '=', id))).delete(];
            this.generateColumnService.where([['table_id', '=', id))).delete(];
            Db.commit();
            return true;
  }

  /**
   * generate
   * 对应 PHP: GenerateService_admin::generate()
   * 逻辑类型: undefined - undefined
   */
  async generate(params: any[]) {
    // 基于PHP真实逻辑: generate
    // PHP原文: if($params['generate_type'] == 2)         {             try {                 $id = $params['id'];                 $table_info = (new GenerateTable())...
if (params.generate_type == 2) {
            try {
                const id = params.id;
                const table_info = this.generateTableService.where([ ['id', '=', id) )).field('*').find().toArray(];
                table_info.fields = this.generateColumnService.where([ ['table_id', '=', id) )).field('*').select().toArray(];

                const generator = this.generateService;
                generator.delOutFiles();

                const flag = array_unique(array_column(table_info, 'table_name')];
                const flag = implode(',', flag);
                generator.setFlag(md5(flag . time())];
                table_info.generate_type = 2;
                generator.generate(table_info);

                const zipFile = '';
                // 生成压缩文件包
                if (generator.getFlag()) {
                    generator.zipFile(];
                    generator.delFlag(];
                    const zipFile = generator.getDownloadUrl(];
                }

                return [file: zipFile);

            } catch ( BusinessException e) {
                throw new AdminBusinessException(e.getMessage()];
            }
  }

  /**
   * preview
   * 对应 PHP: GenerateService_admin::preview()
   * 逻辑类型: undefined - undefined
   */
  async preview(params: any[]) {
    // 基于PHP真实逻辑: preview
    // PHP原文: try {             $id = $params['id'];             $table_info = (new GenerateTable())->where([ ['id', '=', $id] ])->field('*')->find()->toArray();   ...
try {
            const id = params.id;
            const table_info = this.generateTableService.where([ ['id', '=', id) )).field('*').find().toArray(];
            table_info.fields = this.generateColumnService.where([ ['table_id', '=', id) )).field('*').select().toArray(];

            const generateService = app().make(Generate.class];
            table_info.generate_type = 1;
            return generateService.preview(table_info);
  }

  /**
   * getDbFieldType
   * 对应 PHP: GenerateService_admin::getDbFieldType()
   * 逻辑类型: undefined - undefined
   */
  async getDbFieldType(type: string) {
    // 基于PHP真实逻辑: getDbFieldType
    // PHP原文: if (str_starts_with($type, 'set') || str_starts_with($type, 'dict')) {             $result = 'string';...
if (str_starts_with(type, 'set') || str_starts_with(type, 'dict')) {
            const result = 'string';
  }

  /**
   * tableList
   * 对应 PHP: GenerateService_admin::tableList()
   * 逻辑类型: undefined - undefined
   */
  async tableList(params: any[]) {
    // 基于PHP真实逻辑: tableList
    // PHP原文: $sql = 'SHOW TABLE STATUS WHERE 1=1 ';         if (!empty($params['name'])) {             $sql .= "AND name LIKE '%" . $params['name'] . "%'";...
const sql = 'SHOW TABLE STATUS WHERE 1=1 ';
        if (!!params.name)) {
            sql  +=  "AND name LIKE '%" . params.name  + '%'";
  }

  /**
   * checkFile
   * 对应 PHP: GenerateService_admin::checkFile()
   * 逻辑类型: undefined - undefined
   */
  async checkFile(checkFile: any) {
    // 基于PHP真实逻辑: checkFile
    // PHP原文: $info = (new GenerateTable())->where([['id', '=', $checkFile['id']]])->findOrEmpty()->toArray();         $dir = dirname(root_path());         if(empty...
const info = this.generateTableService.where([['id', '=', checkFile.id))).findOrEmpty().toArray(];
        const dir = dirname(root_path()];
        if(!info.class_name))
        {
            info.class_name =  Str.studly(info.table_name);
  }

  /**
   * getTableColumn
   * 对应 PHP: GenerateService_admin::getTableColumn()
   * 逻辑类型: undefined - undefined
   */
  async getTableColumn(data: any) {
    // 基于PHP真实逻辑: getTableColumn
    // PHP原文: $sql = 'SHOW TABLE STATUS WHERE 1=1 ';         $tablePrefix = config('database.connections.mysql.prefix');         if (!empty($data['table_name'])) { ...
const sql = 'SHOW TABLE STATUS WHERE 1=1 ';
        const tablePrefix = config('database.connections.mysql.prefix');
        if (!!data.table_name)) {
            sql  +=  "AND name='" .tablePrefix.data.table_name + ''";
  }

  /**
   * getModels
   * 对应 PHP: GenerateService_admin::getModels()
   * 逻辑类型: undefined - undefined
   */
  async getModels(data: any) {
    // 基于PHP真实逻辑: getModels
    // PHP原文: if($data['addon'] == 'system')         {             //获取系统模型             $modulePath = dirname(root_path()) . '/niucloud/app/model/';             if(...
if (data.addon == 'system') {
            //获取系统模型
            const modulePath = dirname(root_path())  + '/niucloud/app/model/';
            if(!is_dir(modulePath)) {
                return [];
            }
            const modulefiles = glob(modulePath  + '*'];
            const targetFiles = [);
            foreach (modulefiles as file) {
                const fileBaseName = basename(file, '.php');

                if (is_dir(file)) {
                    const file = glob(file  + '/*');
                    foreach (file as item) {
                        if (is_dir(item)) {
                            continue;
                        }
                        targetFiles[] = sprintf(
                            "app\\model\\%s\\%s",
                            fileBaseName,
                            basename(item, '.php')
                        ];
                    }
                } } } else {
                    if (fileBaseName == 'BaseModel') {
                        continue;
                    }
                    targetFiles[] = sprintf(
                        "app\\model\\%s",
                        basename(file, '.php')
                    ;
  }
  }

  /**
   * getModelColumn
   * 对应 PHP: GenerateService_admin::getModelColumn()
   * 逻辑类型: undefined - undefined
   */
  async getModelColumn(data: any) {
    // 基于PHP真实逻辑: getModelColumn
    // PHP原文: $model = new $data['model'];         $table = $model->getModelColumn();         return $table;     }  }...
const model = new data.model;
        const table = model.getModelColumn(];
        return table;
    }

}
  }
}
